#include "TConstructor.h"
#include "common.h"
#define RES_OK 1
#define RES_ERROR 2




TConstructor* TConstructor_Crear()
{
    TConstructor* tmp_tc = (TConstructor*)malloc(sizeof(TConstructor));


    if(!tmp_tc)
    {
        return NULL;
    }
    tmp_tc->countobjects = 0;
    tmp_tc->hasArray = 0;
    tmp_tc->keyPadre = NULL;
    tmp_tc->key = NULL;
    tmp_tc->huboError = 0;
    tmp_tc->errores = NULL;

    return tmp_tc;
}

int Tconstructor_setCola(TConstructor* tc, TCola* cola)
{

   tc->cola = cola;
    return RES_OK;
}

int TConstructor_ComenzarObjeto(TConstructor* tc)
{
     if(tc->countobjects == 0)
     {

       tc->dic = malloc(sizeof(TDiccionario));
       TDiccionaro_Crear(tc->dic);

     }


    tc->countobjects++;
    if(tc->countobjects > 1)
    {
        tc->keyPadre = (char*)malloc(strlen(tc->key) + 2);
        if(tc->keyPadre)
        {
            strcpy(tc->keyPadre, tc->key);
            strcat(tc->keyPadre, "_");
        }
    }
    return RES_OK;
}

int TConstructor_SetClave(TConstructor* tc, char* dato)
{
    int lenPadre = 0;
    if(tc->key)
    {
        free(tc->key);
        tc->key = NULL;

    }
    if(tc->keyPadre)
        lenPadre = strlen(tc->keyPadre);

    tc->key = (char*)malloc(strlen(dato)+1 + lenPadre);

    if(!tc->key)
        return FALSE;

    if(tc->keyPadre)
    {
        strcpy(tc->key, tc->keyPadre);
        strcat(tc->key, dato);
    }else
    {
        strcpy(tc->key, dato);
    }


    return TRUE;
}

int TConstructor_SetValor(TConstructor* tc, void* dato)
{
    TDiccionario_colocar(tc->dic, tc->key, dato);

    return RES_OK;
}

int TConstructor_ValidarTweet(TConstructor* tc)
{
    int i, len, countKey;
    char* Tweetkeys[9] = {"id_str", "text", "retweeted", "created_at", "in_reply_to_status_id_str", "in_reply_to_screen_name",  "source", "user_screen_name", "user_lang"};
    countKey = 0;
    for(i = 0; i < 9; i++)
    {
       len = TDiccionario_sizeDato(tc->dic,Tweetkeys[i] );
        if(!len)
        {
            return FALSE;
        }
        countKey++;

    }

    if(countKey != TDiccionario_Cant_Elementos(tc->dic))
        return FALSE;

    return TRUE;
}

int TConstructor_TerminarObjeto(TConstructor* tc)
{
    int esTweetValido = TConstructor_ValidarTweet(tc);
    tc->countobjects--;
    if(tc->keyPadre)
    {
        free(tc->keyPadre);
        tc->keyPadre = NULL;
    }

    if(tc->countobjects == 0 )
    {
        if(esTweetValido && !tc->huboError)
        {
           if(!tc->hasArray)
             C_Agregar(tc->cola, (void*)tc->dic);
        }else{
            TConstructor_setError(tc, 6, "El Tweet no es valido");
           Tdiccionario_Destruir(tc->dic);
           free(tc->dic);
        }

        tc->huboError = 0;
        tc->dic = NULL;
        tc->hasArray = 0;
    }

    return RES_OK;
}

int TConstructor_IncHasArray(TConstructor* tc){
    if(tc->countobjects)
        tc->hasArray++;
    return RES_OK;
}


int TConstructor_eventoOcurrido(TConstructor* tc, evento evento, void* dato)
{
    switch(evento)
    {
        case CB_COMIENZA_OBJETO:
            TConstructor_ComenzarObjeto(tc);
            break;
        case CB_CLAVE:
            TConstructor_SetClave(tc, (char*)dato);
            break;
        case CB_NULL:
        case CB_FALSE:
        case CB_TRUE:
        case CB_STRING:
        case CB_NUMERO:
            TConstructor_SetValor(tc, dato);
            break;
        case CB_ERROR:
            tc->huboError = 1;
            break;
        case CB_TERMINA_OBJETO:
            TConstructor_TerminarObjeto(tc);
            break;

        case CB_COMIENZA_ARRAY:
        case CB_TERMINA_ARRAY:
            TConstructor_IncHasArray(tc);
            break;

    }

    return RES_OK;
}

void TConstructor_Destruir(TConstructor* tc)
{
    if(tc->dic)
    {
        Tdiccionario_Destruir(tc->dic);
        free(tc->dic);
    }

    free(tc->key);
    if(!C_Vacia(tc->cola[0]))
        C_Vaciar(tc->cola);

    if(tc->errores && !C_Vacia(tc->errores[0]))
        C_Vaciar(tc->errores);

    free(tc);

}

int TConstructor_setError(TConstructor* tc, int codigo, char* mensaje){
    TError error;
   error.codigo = codigo;
   error.descripcion = (char*)malloc(strlen(mensaje)+1);
   if(error.descripcion)
   {
       strcpy(error.descripcion, mensaje);
        C_Agregar(tc->errores,(void*)&error);
        return TRUE;
   }

    return FALSE;
}

int TConstructor_setColaErrores(TConstructor* tc, TCola* cola){
    tc->errores = cola;

    return TRUE;
}






